package dk.bris.webdev;

import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.Iterator;
import java.util.List;

import javax.servlet.Servlet;
import javax.servlet.ServletConfig;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.jdom.Document;
import org.jdom.Element;
import org.jdom.JDOMException;
import org.jdom.input.SAXBuilder;
import org.jdom.output.XMLOutputter;
import org.jdom.xpath.XPath;

/**
 * Servlet implementation class RecipesServlet
 */
public class RecipesServlet extends HttpServlet {
	private static final long serialVersionUID = 1L;

	private Document doc;

	File file;

	/**
	 * @see HttpServlet#HttpServlet()
	 */
	public RecipesServlet() {
		super();
	}

	/**
	 * Please note that that recipes.xml is an existing recipe collection from
	 * xmltek course.
	 * 
	 * @see Servlet#init(ServletConfig)
	 */
	public void init(ServletConfig config) throws ServletException {
		file = new File("Recipes.xml");
		try {
			doc = new SAXBuilder().build(file);
		} catch (JDOMException | IOException e) {
			e.printStackTrace();
		}
	}

	/**
	 * @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse
	 *      response)
	 */
	protected void doGet(HttpServletRequest request,
			HttpServletResponse response) throws ServletException, IOException {

		try {
			boolean found = getRecipeData(
					getRequestName(request.getRequestURI()),
					response.getWriter());
			if (!found)
				response.sendError(404);
		} catch (Exception e) {
			response.sendError(500);
		}
	}

	private String getRequestName(String url) {
		int index = url.lastIndexOf('/');
		return url.substring(index + 1).replace('+', ' ');

	}

	@Override
	protected void doDelete(HttpServletRequest req, HttpServletResponse resp)
			throws ServletException, IOException {
		try {
			boolean found = deleteRecipeData(getRequestName(req.getRequestURI()));
			if (!found)
				resp.sendError(404);

		} catch (JDOMException e) {
			resp.sendError(500);

		}

	}

	@Override
	protected void doPut(HttpServletRequest req, HttpServletResponse resp)
			throws ServletException, IOException {
		try {

			Document tempdoc = new SAXBuilder().build(req.getInputStream());
			XPath xp;
			xp = XPath.newInstance("//rcp:recipe");
			xp.addNamespace("rcp", "http://www.brics.dk/ixwt/recipes");
			List l = xp.selectNodes(tempdoc);
			Iterator ite = l.iterator();
			Element e;
			while (ite.hasNext()) {
				e = (Element) ite.next();
				e.detach();
				doc.getRootElement().addContent(e);
			}

			if (l.size() == 0) {
				resp.sendError(400);
			} else {
				writeDoc();
			}

		} catch (Exception e) {
			resp.sendError(500);
		}

	}

	private boolean deleteRecipeData(String name) throws JDOMException,
			IOException {
		if (doc == null) {
			return false;
		}

		XPath xp;
		if ("".equals(name)) {
			xp = XPath.newInstance("//rcp:recipe");
		} else {
			xp = XPath.newInstance("//rcp:recipe[rcp:title = '" + name + "']");
		}
		xp.addNamespace("rcp", "http://www.brics.dk/ixwt/recipes");
		List l = xp.selectNodes(doc);
		Iterator ite = l.iterator();
		Element e;
		while (ite.hasNext()) {
			e = (Element) ite.next();
			e.detach();
		}

		if (l.size() > 0) {
			writeDoc();
			return true;
		}

		return false;

	}

	private void writeDoc() throws IOException {
		XMLOutputter xout = new XMLOutputter();
		FileWriter writer = new FileWriter(file);
		xout.output(doc, writer);

	}

	private boolean getRecipeData(String name, PrintWriter writer)
			throws JDOMException, IOException {
		if (doc == null) {
			return false;
		}

		XPath xp;
		if ("".equals(name)) {
			xp = XPath.newInstance("//rcp:recipe");
		} else {
			xp = XPath.newInstance("//rcp:recipe[rcp:title = '" + name + "']");
		}
		xp.addNamespace("rcp", "http://www.brics.dk/ixwt/recipes");
		List l = xp.selectNodes(doc);
		if (l.size() > 0) {
			XMLOutputter out = new XMLOutputter();
			out.output(l, writer);
			return true;
		}

		return false;

	}

}
